package com.ccp.dev.workflow.service.bpm.cmd;

import com.ccp.dev.workflow.model.ProcessExecution;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.bpmn.model.InclusiveGateway;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.impl.delegate.InactiveActivityBehavior;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * ClassDescribe:检查条件同步网关，如果具备向下执行的条件，则向下执行
 *
 * @author :jiayueqiao
 * Date: 2020-01-19
 * Since:1
 */
public class CheckInclusiveGatewayCmd implements Command<Boolean> {

    private String procInstId = "";

    public CheckInclusiveGatewayCmd(String procInstId) {
        this.procInstId = procInstId;
    }

    @Override
    public Boolean execute(CommandContext commandContext) {
        //存储已经检查过的执行流的节点
        Map hasChecked= new HashMap(16);
        checkInclusiveGateWay(procInstId,hasChecked);
        return null;
    }

    private void checkInclusiveGateWay(String procInstId,Map hasChecked){
        //是否继续检查
        boolean continueCheck = false;
        //查询所有的子执行流
        List<ExecutionEntity> processExecutionList = CommandContextUtil.getExecutionEntityManager().findChildExecutionsByProcessInstanceId(procInstId);
        //遍历执行流
        Iterator<ExecutionEntity> executionIterator = processExecutionList.iterator();
        while(executionIterator.hasNext()) {
            ExecutionEntity executionEntity = executionIterator.next();
            String activityId = executionEntity.getActivityId();
            String procDefId = executionEntity.getProcessDefinitionId();
            String executionId = executionEntity.getId();
            Process process = ProcessDefinitionUtil.getProcess(procDefId);
            FlowNode flowNode = (FlowNode) process.getFlowElement(activityId, true);
            String key = executionId+"_"+activityId;
            //若当前节点的执行流所处的节点是条件同步分支节点，则进行是否结束该条件分支的逻辑判断
            if(flowNode instanceof InclusiveGateway && !hasChecked.containsKey(key)){
                InactiveActivityBehavior inactiveActivityBehavior = ((InactiveActivityBehavior) flowNode.getBehavior());
                inactiveActivityBehavior.executeInactive(executionEntity);
                //由于节点向下执行后会影响执行流，因此结束该循环，重新开始一轮检查
                continueCheck = true;
                hasChecked.put(key,"");
                break;
            }
        }
        if(continueCheck){
            checkInclusiveGateWay(procInstId,hasChecked);
        }
    }

}
